﻿namespace CloudNinja.Metering.Tests.ConfigSection
{
    using System;
    using System.Configuration;
    using System.IO;
    using System.Linq;

    using CloudNinja.Metering.Common.Configuration;
    using CloudNinja.Metering.Providers.AzureBlob;
    using CloudNinja.Metering.Providers.Configuration;
    using CloudNinja.Metering.Providers.Configuration.BlobBandwidth;
    using CloudNinja.Metering.Providers.Configuration.BlobSize;
    using CloudNinja.Metering.Providers.Configuration.DatabaseBandwidth;
    using CloudNinja.Metering.Providers.Configuration.DatabaseSize;
    using CloudNinja.Metering.Providers.Configuration.IISLog;
    using CloudNinja.Metering.Providers.SQLAzure;
    using CloudNinja.Metering.Providers.WebRole;

    using Xunit;

    public class ConfigSectionTests
    {
        [Fact]
        public void CanCreateWithNoProviers()
        {
            var meteringSection = new MeteringSection
                {
                    CommonSettings =
                        new CommonSettingsElement
                            {
                                ConnectionStrings =
                                    new ConnectionStringsCollection
                                        {
                                            new ConnectionStringElement
                                                { Name = "Common", Value = "UseDevelopmentStorage=true" }
                                        },
                                BlockConnectionString = "UseDevelopmentStorage=true"
                            },
                    MeteringRepositorySettings =
                        new MeteringRepositorySettingsElement { APIKey = GlobalTestSettings.APIKey, UserId = "test" }
                };

            if (File.Exists("noproviders.config"))
            {
                File.Delete("noproviders.config");
            }

            this.CreateConfigFile("noproviders", meteringSection);

            var readConfig = this.ReadConfigFile("noproviders");

            Assert.NotNull(readConfig);

            Assert.Equal(readConfig.CommonSettings.ConnectionStrings[0].Name, meteringSection.CommonSettings.ConnectionStrings[0].Name);

            Assert.Equal(readConfig.CommonSettings.ConnectionStrings[0].Value, meteringSection.CommonSettings.ConnectionStrings[0].Value);

            Assert.Equal(readConfig.MeteringRepositorySettings.APIKey, meteringSection.MeteringRepositorySettings.APIKey);

            Assert.Equal(readConfig.MeteringRepositorySettings.UserId, meteringSection.MeteringRepositorySettings.UserId);
        }

        [Fact]
        public void CanCreateFullFile()
        {
            var meteringSection = new MeteringSection
                {
                    CommonSettings =
                        new CommonSettingsElement
                            {
                                ConnectionStrings =
                                    new ConnectionStringsCollection
                                        {
                                            new ConnectionStringElement
                                                { Name = "Common", Value = "UseDevelopmentStorage=true" }
                                        },
                                BlockConnectionString = "UseDevelopmentStorage=true"
                            },
                    MeteringRepositorySettings =
                        new MeteringRepositorySettingsElement { APIKey = GlobalTestSettings.APIKey, UserId = "test" },
                    ProviderSettings =
                        {
                            Providers =
                                new ProvidersCollection
                                    {
                                        new BlobSizeProviderElement
                                            {
                                                Type = typeof(BlobSizeProvider).AssemblyQualifiedName,
                                                BlobSizeMeteringMeteringProviderSettings =
                                                    new BlobSizeMeteringProviderSettings
                                                        {
                                                            DefaultTenantIdPattern = "tnt_{.+}",
                                                            StorageAccounts =
                                                                new BlobSizeStorageAccountsCollection
                                                                    {
                                                                        new BlobSizeCollectionElement
                                                                            {
                                                                                Name = "Storage1",
                                                                                ConnectionString = "UseDevelopmentStorage=true",
                                                                                TenantIdPattern = "tn_{.+}"
                                                                            },
                                                                        new BlobSizeCollectionElement
                                                                            {
                                                                                Name = "Storage2",
                                                                                ConnectionString = "UseDevelopmentStorage=true",
                                                                                TenantIdPattern = "ten_{.+}"
                                                                            }
                                                                    }
                                                        }
                                            },
                                        new IISLogMeteringProviderElement
                                            {
                                                CollectInterval = TimeSpan.FromHours(5),
                                                Type = typeof(IISLogProvider).AssemblyQualifiedName,
                                                ProviderSettings =
                                                    new IISLogMeteringProviderSettings
                                                        {
                                                            IISLogsParserBookmarkRepository = "UseDevelopmentStorage=true",
                                                            TenantIdentifierLocation = "hostheader",
                                                            TenantIdentifierPattern = "{.*}.thecloudninja.com"
                                                        }
                                            },
                                        new DatabaseSizeMeteringProviderElement
                                            {
                                                CollectInterval = TimeSpan.FromSeconds(30),
                                                Type = typeof(DatabaseSizeProvider).AssemblyQualifiedName,
                                                DatabaseSizeMeteringProviderSettings =
                                                    new DatabaseSizeMeteringProviderSettings
                                                        {
                                                            DefaultTenantIdPattern = "tnt_{.+}",
                                                            DatabaseServers =
                                                                new DatabaseServersCollection
                                                                    {
                                                                        new DatabaseServersCollectionElement
                                                                            {
                                                                                Name = "Server1",
                                                                                Value =
                                                                                    GlobalTestSettings.DatabaseConnectionString,
                                                                                TenantIdPattern = "tnt_{.+}"
                                                                            }
                                                                    }
                                                        }
                                            },
                                        new DatabaseBandwidthMeteringProviderElement
                                            {
                                                CollectInterval = TimeSpan.FromSeconds(30),
                                                Type =
                                                    typeof(DatabaseBandwidthUsageProvider).AssemblyQualifiedName,
                                                DatabaseBandwidthMeteringProviderSettings =
                                                    new DatabaseBandwidthMeteringProviderSettings
                                                        {
                                                            DefaultTenantIdPattern = "tnt_{.+}",
                                                            DatabaseServers =
                                                                new DatabaseServersCollection
                                                                    {
                                                                        new DatabaseServersCollectionElement
                                                                            {
                                                                                Name = "Server1",
                                                                                Value =
                                                                                    GlobalTestSettings.DatabaseConnectionString,
                                                                                TenantIdPattern = "tnt_{.+}"
                                                                            }
                                                                    }
                                                        }
                                            },
                                        new BlobBandwidthProviderElement
                                            {
                                                CollectInterval = TimeSpan.FromHours(1),
                                                Type = typeof(BlobBandwidthProvider).AssemblyQualifiedName,
                                                BlobBandwidthMeteringProviderSettings =
                                                    new BlobBandwidthMeteringProviderSettings
                                                        {
                                                            DefaultTenantIdPattern = "tnt_{.+}",
                                                            StorageAccounts =
                                                                new BlobBandwithStorageAccountsCollection
                                                                    {
                                                                        new BlobBandwidthCollectionElement
                                                                            {
                                                                                ConnectionString = "connection string",
                                                                                Name = "name"
                                                                            }
                                                                    }
                                                        }
                                            }
                                    }
                        }
                };

            if (File.Exists("fullConfig.config"))
            {
                File.Delete("fullConfig.config");
            }

            this.CreateConfigFile("fullConfig", meteringSection);

            var readMeteringSection = this.ReadConfigFile("fullConfig");

            var blockConnectionString = readMeteringSection.CommonSettings.BlockConnectionString;

            Assert.Equal("UseDevelopmentStorage=true", blockConnectionString);

            Assert.Equal(5, readMeteringSection.ProviderSettings.Providers.Count);

            // IISLogMeteringProvider
            Assert.True(readMeteringSection.ProviderSettings.Providers.OfType<IISLogMeteringProviderElement>().Count() == 1);
            var iisProviderSettings = readMeteringSection.ProviderSettings.Providers.OfType<IISLogMeteringProviderElement>().First();
            Assert.Equal("UseDevelopmentStorage=true", iisProviderSettings.ProviderSettings.IISLogsParserBookmarkRepository);

            //DatabaseSizeMeteringProviderElement
            Assert.True(readMeteringSection.ProviderSettings.Providers.OfType<DatabaseSizeMeteringProviderElement>().Count() == 1);
            var dbSizeProviderSettings = readMeteringSection.ProviderSettings.Providers.OfType<DatabaseSizeMeteringProviderElement>().First();
            Assert.Equal(1, dbSizeProviderSettings.DatabaseSizeMeteringProviderSettings.DatabaseServers.Count);

            // DatabaseBandwidthMeteringProviderElement
            Assert.True(readMeteringSection.ProviderSettings.Providers.OfType<DatabaseBandwidthMeteringProviderElement>().Count() == 1);
            var dbBandwidthProviderSettings = readMeteringSection.ProviderSettings.Providers.OfType<DatabaseBandwidthMeteringProviderElement>().First();
            Assert.Equal(1, dbBandwidthProviderSettings.DatabaseBandwidthMeteringProviderSettings.DatabaseServers.Count);

            // BlobBandwidthProviderElement
            Assert.True(readMeteringSection.ProviderSettings.Providers.OfType<BlobBandwidthProviderElement>().Count() == 1);
            var bandwidthProviderSettings = readMeteringSection.ProviderSettings.Providers.OfType<BlobBandwidthProviderElement>().First();
            Assert.Equal(1, bandwidthProviderSettings.BlobBandwidthMeteringProviderSettings.StorageAccounts.Count);
            Assert.Equal(TimeSpan.FromHours(1), bandwidthProviderSettings.CollectInterval);

            // BlobSizeProviderElement
            Assert.True(readMeteringSection.ProviderSettings.Providers.OfType<BlobSizeProviderElement>().Count() == 1);
            var BlobSizeProviderSettings = readMeteringSection.ProviderSettings.Providers.OfType<BlobSizeProviderElement>().First();
            Assert.Equal("tnt_{.+}", BlobSizeProviderSettings.BlobSizeMeteringMeteringProviderSettings.DefaultTenantIdPattern);
        }

        [Fact]
        public void CanReadDefaultIfNoDurationSet()
        {
            var meteringSection = new MeteringSection
            {
                CommonSettings =
                    new CommonSettingsElement
                    {
                        ConnectionStrings =
                            new ConnectionStringsCollection
                                        {
                                            new ConnectionStringElement
                                                { Name = "Common", Value = "UseDevelopmentStorage=true" }
                                        },
                        BlockConnectionString = "UseDevelopmentStorage=true"
                    },
                MeteringRepositorySettings =
                    new MeteringRepositorySettingsElement { APIKey = GlobalTestSettings.APIKey, UserId = "test" },
                ProviderSettings =
                {
                    DefaultCollectionInterval = TimeSpan.FromMinutes(15),
                    Providers =
                        new ProvidersCollection
                                    {
                                        new BlobSizeProviderElement
                                            {
                                                Type = typeof(BlobSizeProvider).AssemblyQualifiedName,
                                                BlobSizeMeteringMeteringProviderSettings =
                                                    new BlobSizeMeteringProviderSettings
                                                        {
                                                            DefaultTenantIdPattern = "tnt_{.+}",
                                                            StorageAccounts =
                                                                new BlobSizeStorageAccountsCollection
                                                                    {
                                                                        new BlobSizeCollectionElement
                                                                            {
                                                                                Name = "Storage1",
                                                                                ConnectionString = "UseDevelopmentStorage=true",
                                                                                TenantIdPattern = "ten_{.+}",
                                                                                TenantsBaseContainerPrefix = "tenants"
                                                                            },
                                                                       new BlobSizeCollectionElement
                                                                            {
                                                                                Name = "Storage2",
                                                                                ConnectionString = "UseDevelopmentStorage=true",
                                                                                TenantIdPattern = "tnt_{.+}",
                                                                                TenantsBaseContainerPrefix = "tenants"
                                                                            }
                                                                    }
                                                        }
                                            },
                                        new IISLogMeteringProviderElement
                                            {
                                                Type = typeof(IISLogProvider).AssemblyQualifiedName,
                                                ProviderSettings =
                                                    new IISLogMeteringProviderSettings
                                                        {
                                                            IISLogsParserBookmarkRepository = "UseDevelopmentStorage=true",
                                                            TenantIdentifierLocation = "hostheader",
                                                            TenantIdentifierPattern = "{.*}.thecloudninja.com"
                                                        }
                                            },
                                        new DatabaseSizeMeteringProviderElement
                                            {
                                                Type = typeof(DatabaseSizeProvider).AssemblyQualifiedName,
                                                DatabaseSizeMeteringProviderSettings =
                                                    new DatabaseSizeMeteringProviderSettings
                                                        {
                                                            DefaultTenantIdPattern = "tnt_{.+}",
                                                            DatabaseServers =
                                                                new DatabaseServersCollection
                                                                    {
                                                                        new DatabaseServersCollectionElement
                                                                            {
                                                                                Name = "Server1",
                                                                                Value =
                                                                                    GlobalTestSettings.DatabaseConnectionString,
                                                                                TenantIdPattern = "tnt_{.+}"
                                                                            }
                                                                    }
                                                        }
                                            },
                                        new DatabaseBandwidthMeteringProviderElement
                                            {
                                                Type =
                                                    typeof(DatabaseBandwidthUsageProvider).AssemblyQualifiedName,
                                                DatabaseBandwidthMeteringProviderSettings =
                                                    new DatabaseBandwidthMeteringProviderSettings
                                                        {
                                                            DefaultTenantIdPattern = "tnt_{.+}",
                                                            DatabaseServers =
                                                                new DatabaseServersCollection
                                                                    {
                                                                        new DatabaseServersCollectionElement
                                                                            {
                                                                                Name = "Server1",
                                                                                Value =
                                                                                    GlobalTestSettings.DatabaseConnectionString,
                                                                                TenantIdPattern = "tnt_{.+}"
                                                                            }
                                                                    }
                                                        }
                                            },
                                        new BlobBandwidthProviderElement
                                            {
                                                Type = typeof(BlobBandwidthProvider).AssemblyQualifiedName,
                                                BlobBandwidthMeteringProviderSettings =
                                                    new BlobBandwidthMeteringProviderSettings
                                                        {
                                                            DefaultTenantIdPattern = "tnt_{.+}",
                                                            StorageAccounts =
                                                                new BlobBandwithStorageAccountsCollection
                                                                    {
                                                                        new BlobBandwidthCollectionElement
                                                                            {
                                                                                ConnectionString = "connection string",
                                                                                Name = "name",
                                                                                TenantIdPattern = "ten_{.+}"
                                                                            }
                                                                    }
                                                        }
                                            }
                                    }
                }
            };

            if (File.Exists("noSetCollectTime.config"))
            {
                File.Delete("noSetCollectTime.config");
            }

            this.CreateConfigFile("noSetCollectTime", meteringSection);

            var readMeteringSection = this.ReadConfigFile("noSetCollectTime");

            var defaultCollectValuePreset = false;

            foreach (var p in from object provider in readMeteringSection.ProviderSettings.Providers select provider as ProviderElement)
            {
                defaultCollectValuePreset = p.CollectInterval.Equals(TimeSpan.FromMinutes(15));
            }

            Assert.True(defaultCollectValuePreset);
        }

        [Fact]
        public void ProvidersReferringToCommonConnStrings()
        {
            var meteringSection = new MeteringSection
            {
                CommonSettings =
                    new CommonSettingsElement
                    {
                        ConnectionStrings =
                            new ConnectionStringsCollection
                                        {
                                            new ConnectionStringElement
                                                { Name = "CommonAzureStore", Value = "UseDevelopmentStorage=true" },
                                            new ConnectionStringElement
                                                { Name = "CommonDatabase", Value = GlobalTestSettings.DatabaseConnectionString },
                                        },
                        BlockConnectionString = "UseDevelopmentStorage=true"
                    },
                MeteringRepositorySettings =
                    new MeteringRepositorySettingsElement { APIKey = GlobalTestSettings.APIKey, UserId = "test" },
                ProviderSettings =
                {
                    DefaultCollectionInterval = TimeSpan.FromMinutes(15),
                    Providers =
                        new ProvidersCollection
                                    {
                                        new BlobSizeProviderElement
                                            {
                                                Type = typeof(BlobSizeProvider).AssemblyQualifiedName,
                                                BlobSizeMeteringMeteringProviderSettings =
                                                    new BlobSizeMeteringProviderSettings
                                                        {
                                                            DefaultTenantIdPattern = "tnt_{.+}",
                                                            StorageAccounts =
                                                                new BlobSizeStorageAccountsCollection
                                                                    {
                                                                        new BlobSizeCollectionElement
                                                                            {
                                                                                Name = "Storage1",
                                                                                ConnectionString = "CommonAzureStore",
                                                                                TenantIdPattern = "ten_{.+}",
                                                                                TenantsBaseContainerPrefix = "tenants"
                                                                            }
                                                                    }
                                                        }
                                            },
                                        new IISLogMeteringProviderElement
                                            {
                                                Type = typeof(IISLogProvider).AssemblyQualifiedName,
                                                ProviderSettings =
                                                    new IISLogMeteringProviderSettings
                                                        {
                                                            IISLogsParserBookmarkRepository = "CommonAzureStore",
                                                            TenantIdentifierLocation = "hostheader",
                                                            TenantIdentifierPattern = "{.*}.thecloudninja.com"
                                                        }
                                            },
                                        new DatabaseSizeMeteringProviderElement
                                            {
                                                Type = typeof(DatabaseSizeProvider).AssemblyQualifiedName,
                                                DatabaseSizeMeteringProviderSettings =
                                                    new DatabaseSizeMeteringProviderSettings
                                                        {
                                                            DefaultTenantIdPattern = "tnt_{.+}",
                                                            DatabaseServers =
                                                                new DatabaseServersCollection
                                                                    {
                                                                        new DatabaseServersCollectionElement
                                                                            {
                                                                                Name = "Server1",
                                                                                Value =
                                                                                    "CommonDatabase",
                                                                                TenantIdPattern = "tnt_{.+}"
                                                                            }
                                                                    }
                                                        }
                                            },
                                        new DatabaseBandwidthMeteringProviderElement
                                            {
                                                Type =
                                                    typeof(DatabaseBandwidthUsageProvider).AssemblyQualifiedName,
                                                DatabaseBandwidthMeteringProviderSettings =
                                                    new DatabaseBandwidthMeteringProviderSettings
                                                        {
                                                            DefaultTenantIdPattern = "tnt_{.+}",
                                                            DatabaseServers =
                                                                new DatabaseServersCollection
                                                                    {
                                                                        new DatabaseServersCollectionElement
                                                                            {
                                                                                Name = "Server1",
                                                                                Value =
                                                                                    "CommonDatabase",
                                                                                TenantIdPattern = "tnt_{.+}"
                                                                            }
                                                                    }
                                                        }
                                            },
                                        new BlobBandwidthProviderElement
                                            {
                                                Type = typeof(BlobBandwidthProvider).AssemblyQualifiedName,
                                                BlobBandwidthMeteringProviderSettings =
                                                    new BlobBandwidthMeteringProviderSettings
                                                        {
                                                            DefaultTenantIdPattern = "tnt_{.+}",
                                                            StorageAccounts =
                                                                new BlobBandwithStorageAccountsCollection
                                                                    {
                                                                        new BlobBandwidthCollectionElement
                                                                            {
                                                                                ConnectionString = "CommonAzureStore",
                                                                                Name = "name",
                                                                                TenantIdPattern = "tnt_{.+}"
                                                                            }
                                                                    }
                                                        }
                                            }
                                    }
                }
            };

            if (File.Exists("defaultConnectionNames.config"))
            {
                File.Delete("defaultConnectionNames.config");
            }

            this.CreateConfigFile("defaultConnectionNames", meteringSection);

            var readMeteringSection = this.ReadConfigFile("defaultConnectionNames");

            // IISLogMeteringProvider
            Assert.True(readMeteringSection.ProviderSettings.Providers.OfType<IISLogMeteringProviderElement>().Count() == 1);
            var iisProviderSettings = readMeteringSection.ProviderSettings.Providers.OfType<IISLogMeteringProviderElement>().First();
            Assert.Equal("UseDevelopmentStorage=true", iisProviderSettings.ProviderSettings.IISLogsParserBookmarkRepository);

            //DatabaseSizeMeteringProviderElement
            Assert.True(readMeteringSection.ProviderSettings.Providers.OfType<DatabaseSizeMeteringProviderElement>().Count() == 1);
            var dbSizeProviderSettings = readMeteringSection.ProviderSettings.Providers.OfType<DatabaseSizeMeteringProviderElement>().First();
            Assert.True(dbSizeProviderSettings.DatabaseSizeMeteringProviderSettings.DatabaseServers.Count == 1);
            Assert.Equal(
                GlobalTestSettings.DatabaseConnectionString,
                dbSizeProviderSettings.DatabaseSizeMeteringProviderSettings.DatabaseServers[0].Value);

            // DatabaseBandwidthMeteringProviderElement
            Assert.True(readMeteringSection.ProviderSettings.Providers.OfType<DatabaseBandwidthMeteringProviderElement>().Count() == 1);
            var dbBandwidthProviderSettings = readMeteringSection.ProviderSettings.Providers.OfType<DatabaseBandwidthMeteringProviderElement>().First();
            Assert.Equal(1, dbBandwidthProviderSettings.DatabaseBandwidthMeteringProviderSettings.DatabaseServers.Count);
            Assert.Equal(GlobalTestSettings.DatabaseConnectionString, dbBandwidthProviderSettings.DatabaseBandwidthMeteringProviderSettings.DatabaseServers[0].Value);

            // BlobBandwidthProviderElement
            Assert.True(readMeteringSection.ProviderSettings.Providers.OfType<BlobBandwidthProviderElement>().Count() == 1);
            var bandwidthProviderSettings = readMeteringSection.ProviderSettings.Providers.OfType<BlobBandwidthProviderElement>().First();
            Assert.Equal(1, bandwidthProviderSettings.BlobBandwidthMeteringProviderSettings.StorageAccounts.Count);
            Assert.Equal("UseDevelopmentStorage=true", bandwidthProviderSettings.BlobBandwidthMeteringProviderSettings.StorageAccounts[0].ConnectionString);

            // BlobSizeProviderElement
            Assert.True(readMeteringSection.ProviderSettings.Providers.OfType<BlobSizeProviderElement>().Count() == 1);
            var blobSizeProviderSettings = readMeteringSection.ProviderSettings.Providers.OfType<BlobSizeProviderElement>().First();
            Assert.Equal(1, blobSizeProviderSettings.BlobSizeMeteringMeteringProviderSettings.StorageAccounts.Count);
            Assert.Equal("UseDevelopmentStorage=true", blobSizeProviderSettings.BlobSizeMeteringMeteringProviderSettings.StorageAccounts[0].ConnectionString);
        }

        private void CreateConfigFile(string configurationName, MeteringSection meteringSection)
        {
            var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            if (config.Sections["MeteringConfiguration"] == null)
            {
                config.Sections.Add("MeteringConfiguration", meteringSection);
            }

            meteringSection.SectionInformation.ForceSave = true;

            config.SaveAs(configurationName + ".config");
        }

        private MeteringSection ReadConfigFile(string configurationName)
        {
            var configFileMap = new ExeConfigurationFileMap { ExeConfigFilename = configurationName + ".config" };
            var config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None);

            return config.GetSection("MeteringConfiguration") as MeteringSection;
        }



        [Fact]
        public void CanGetDefaulTenantPatterns()
        {
            var defaultTenantPattern = "tnt_{.+}";

            var meteringSection = new MeteringSection
                {
                    CommonSettings =
                        new CommonSettingsElement
                            {
                                ConnectionStrings =
                                    new ConnectionStringsCollection
                                        {
                                            new ConnectionStringElement
                                                { Name = "CommonAzureStore", Value = "UseDevelopmentStorage=true" },
                                            new ConnectionStringElement
                                                {
                                                    Name = "CommonDatabase",
                                                    Value =
                                                        GlobalTestSettings.DatabaseConnectionString
                                                },
                                        },
                                BlockConnectionString = "UseDevelopmentStorage=true"
                            },
                    MeteringRepositorySettings =
                        new MeteringRepositorySettingsElement { APIKey = GlobalTestSettings.APIKey, UserId = "test" },
                    ProviderSettings =
                        {
                            DefaultCollectionInterval = TimeSpan.FromMinutes(15),
                            Providers =
                                new ProvidersCollection
                                    {
                                        new BlobSizeProviderElement
                                            {
                                                Type = typeof(BlobSizeProvider).AssemblyQualifiedName,
                                                BlobSizeMeteringMeteringProviderSettings =
                                                    new BlobSizeMeteringProviderSettings
                                                        {
                                                            DefaultTenantIdPattern = defaultTenantPattern,
                                                            StorageAccounts =
                                                                new BlobSizeStorageAccountsCollection
                                                                    {
                                                                        new BlobSizeCollectionElement
                                                                            {
                                                                                Name = "Storage1",
                                                                                ConnectionString = "CommonAzureStore",
                                                                                TenantsBaseContainerPrefix = "tenants"
                                                                            }
                                                                    }
                                                        }
                                            },
                                        new IISLogMeteringProviderElement
                                            {
                                                Type = typeof(IISLogProvider).AssemblyQualifiedName,
                                                ProviderSettings =
                                                    new IISLogMeteringProviderSettings
                                                        {
                                                            IISLogsParserBookmarkRepository = "CommonAzureStore",
                                                            TenantIdentifierLocation = "hostheader",
                                                            TenantIdentifierPattern = "{.*}.thecloudninja.com"
                                                        }
                                            },
                                        new DatabaseSizeMeteringProviderElement
                                            {
                                                Type = typeof(DatabaseSizeProvider).AssemblyQualifiedName,
                                                DatabaseSizeMeteringProviderSettings =
                                                    new DatabaseSizeMeteringProviderSettings
                                                        {
                                                            DefaultTenantIdPattern = defaultTenantPattern,
                                                            DatabaseServers =
                                                                new DatabaseServersCollection
                                                                    {
                                                                        new DatabaseServersCollectionElement
                                                                            { Name = "Server1", Value = "CommonDatabase" }
                                                                    }
                                                        }
                                            },
                                        new DatabaseBandwidthMeteringProviderElement
                                            {
                                                Type =
                                                    typeof(DatabaseBandwidthUsageProvider).AssemblyQualifiedName,
                                                DatabaseBandwidthMeteringProviderSettings =
                                                    new DatabaseBandwidthMeteringProviderSettings
                                                        {
                                                            DefaultTenantIdPattern = defaultTenantPattern,
                                                            DatabaseServers =
                                                                new DatabaseServersCollection
                                                                    {
                                                                        new DatabaseServersCollectionElement
                                                                            { Name = "Server1", Value = "CommonDatabase" }
                                                                    }
                                                        }
                                            },
                                        new BlobBandwidthProviderElement
                                            {
                                                Type = typeof(BlobBandwidthProvider).AssemblyQualifiedName,
                                                BlobBandwidthMeteringProviderSettings =
                                                    new BlobBandwidthMeteringProviderSettings
                                                        {
                                                            DefaultTenantIdPattern = defaultTenantPattern,
                                                            StorageAccounts =
                                                                new BlobBandwithStorageAccountsCollection
                                                                    {
                                                                        new BlobBandwidthCollectionElement
                                                                            {
                                                                                ConnectionString = "CommonAzureStore",
                                                                                Name = "name"
                                                                            }
                                                                    }
                                                        }
                                            }
                                    }
                        }
                };

            if (File.Exists("defaultTenantPattern.config"))
            {
                File.Delete("defaultTenantPattern.config");
            }

            this.CreateConfigFile("defaultTenantPattern", meteringSection);

            var readMeteringSection = this.ReadConfigFile("defaultTenantPattern");

            //DatabaseSizeMeteringProviderElement
            Assert.True(
                readMeteringSection.ProviderSettings.Providers.OfType<DatabaseSizeMeteringProviderElement>().Count()
                == 1);
            var dbSizeProviderSettings =
                readMeteringSection.ProviderSettings.Providers.OfType<DatabaseSizeMeteringProviderElement>().First();
            Assert.True(dbSizeProviderSettings.DatabaseSizeMeteringProviderSettings.DatabaseServers.Count == 1);
            Assert.Equal(
                defaultTenantPattern,
                dbSizeProviderSettings.DatabaseSizeMeteringProviderSettings.DatabaseServers[0].TenantIdPattern);

            // DatabaseBandwidthMeteringProviderElement
            Assert.True(readMeteringSection.ProviderSettings.Providers.OfType<DatabaseBandwidthMeteringProviderElement>().Count() == 1);
            var dbBandwidthProviderSettings = readMeteringSection.ProviderSettings.Providers.OfType<DatabaseBandwidthMeteringProviderElement>().First();
            Assert.Equal(1, dbBandwidthProviderSettings.DatabaseBandwidthMeteringProviderSettings.DatabaseServers.Count);
            Assert.Equal(defaultTenantPattern, dbBandwidthProviderSettings.DatabaseBandwidthMeteringProviderSettings.DatabaseServers[0].TenantIdPattern);

            // BlobBandwidthProviderElement
            Assert.True(readMeteringSection.ProviderSettings.Providers.OfType<BlobBandwidthProviderElement>().Count() == 1);
            var bandwidthProviderSettings = readMeteringSection.ProviderSettings.Providers.OfType<BlobBandwidthProviderElement>().First();
            Assert.Equal(1, bandwidthProviderSettings.BlobBandwidthMeteringProviderSettings.StorageAccounts.Count);
            Assert.Equal(defaultTenantPattern, bandwidthProviderSettings.BlobBandwidthMeteringProviderSettings.StorageAccounts[0].TenantIdPattern);

            // BlobSizeProviderElement
            Assert.True(readMeteringSection.ProviderSettings.Providers.OfType<BlobSizeProviderElement>().Count() == 1);
            var blobSizeProviderSettings = readMeteringSection.ProviderSettings.Providers.OfType<BlobSizeProviderElement>().First();
            Assert.Equal(1, blobSizeProviderSettings.BlobSizeMeteringMeteringProviderSettings.StorageAccounts.Count);
            Assert.Equal(defaultTenantPattern, blobSizeProviderSettings.BlobSizeMeteringMeteringProviderSettings.StorageAccounts[0].TenantIdPattern);
        }
    }
}
